<template>
  <!-- 列表设置 -->
  <HModal :model-value="dialogTableVisible" title="列表设置" @close="onCancel">
    <div v-loading="loading" element-loading-text="加载中...">
      <div class="header_Table">
        <span
          :class="onTitleIndex == 1 ? 'title_color' : ''"
          class="title_xy"
          @click="onClickTitleIndex(1)"
          >表头字段</span
        >
        <span
          :class="onTitleIndex == 2 ? 'title_color' : ''"
          class="title_xy"
          @click="onClickTitleIndex(2)"
          >列表排序</span
        >
      </div>
      <div v-if="onTitleIndex == 1">
        <section class="operate_btn_group">
          <HLink @click="onDefault">恢复默认</HLink>
          <HLink @click="isShowAll(true)">全部显示</HLink>
          <HLink @click="isShowAll(false)">全部隐藏</HLink>
          <HLink @click="onMoveUp">上移</HLink>
          <HLink @click="onMoveDown">下移</HLink>
          <HLink @click="onIsFreezeAll(true)">全部冻结</HLink>
          <HLink @click="onIsFreezeAll(false)">全部解冻</HLink>
          <el-popover
            ref="popover"
            :width="300"
            placement="left-end"
            title="操作"
            trigger="click"
            @before-enter="popoverShow"
          >
            <template #reference>
              <HLink>移到</HLink>
            </template>
            <div style="display: flex; justify-content: end; align-items: center; gap: 12px">
              <HLink @click="onMoveFirst">首行</HLink>
              <HLink @click="onMoveLast">末尾</HLink>
            </div>
            <div
              v-if="HeaderDataList.length > 0"
              style="display: flex; align-items: center; margin: 16px 0 12px; gap: 12px"
            >
              <span style="margin-right: 12px">移动到</span>
              <el-input-number
                v-model.trim="numInput"
                :max="HeaderDataList.length"
                :min="1"
                placeholder="行"
              />
              <HButton type="primary" @click="onMoveTo(numInput)">确认</HButton>
            </div>
          </el-popover>
        </section>

        <!-- row-key一定要确定唯一性，否则会出现异常 -->
        <el-table
          ref="multipleTableRef"
          :data="HeaderDataList"
          height="60vh"
          row-key="name"
          @selection-change="handleSelectionChange"
        >
          <!--选择-->
          <el-table-column type="selection" width="40" />

          <!--序号-->
          <el-table-column label="序号" type="index" width="50" />

          <!--表头名称-->
          <el-table-column label="表头名称" property="initFieldName" width="130" />

          <!--自定义表头名称-->
          <el-table-column label="自定义表头名称" width="180">
            <template #default="i">
              <el-input v-model.trim="i.row.name" placeholder="可修改名称"></el-input>
            </template>
          </el-table-column>

          <!--显示列-->
          <el-table-column label="显示列" width="130">
            <template #default="i">
              <div style="display: flex; align-items: center; gap: 0.7vw">
                <el-switch v-model="i.row.showColumn" />
                <span v-if="i.row.showColumn">显示</span>
                <span v-else>隐藏</span>
              </div>
            </template>
          </el-table-column>

          <!--冻结列-->
          <el-table-column label="冻结列" width="130">
            <template #default="scope">
              <div style="display: flex; align-items: center; gap: 0.7vw">
                <el-switch v-model="scope.row.freezeColumn" />
                <span v-if="scope.row.freezeColumn">冻结</span>
                <span v-else>不冻结</span>
              </div>
            </template>
          </el-table-column>

          <!--操作-->
          <el-table-column align="center" label="操作">
            <template #default="i">
              <!--  @mousedown="fieldSort($event, i.$index)" -->
              <el-icon
                draggable
                size="16"
                style="
                  display: flex;
                  width: 100%;
                  align-items: center;
                  justify-content: center;
                  cursor: move;
                  height: 100%;
                "
                @dragend="dragend(i.$index)"
                @dragenter="dragenter($event, i.$index)"
                @dragover="dragover($event)"
              >
                <Sort />
              </el-icon>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div v-if="onTitleIndex == 2">
        <section class="list_option">
          <HLink
            v-for="(item, index) in optionsTable"
            :key="index"
            @click="onClickoptionsTableData(index)"
            >{{ item }}</HLink
          >
        </section>
        <el-table :data="TableDataList" height="60vh" @selection-change="handleSelectionChange">
          <!--选择-->
          <el-table-column type="selection" width="40" />

          <!--序号-->
          <el-table-column fixed="left" label="序号" min-width="50" type="index" />

          <!--工单状态-->
          <el-table-column label="工单状态" property="name" width="140">
            <template #default="scope">
              {{ typeState[scope.row.type - 1].name }}
            </template>
          </el-table-column>

          <!--条件-->
          <el-table-column align="center" label="条件">
            <template #default="scope">
              <el-select v-model="scope.row.orderByField" placeholder="Select" style="width: 80%">
                <el-option
                  v-for="(item, index) in options"
                  :key="index"
                  :label="item"
                  :value="index + 1"
                />
              </el-select>
            </template>
          </el-table-column>

          <!--排序-->
          <el-table-column align="center" label="排序">
            <template #default="scope">
              <el-select v-model="scope.row.orderBy" placeholder="Select" style="width: 70%">
                <el-option :value="1" label="升序" />
                <el-option :value="2" label="倒序" />
              </el-select>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>
    <template #footerRight>
      <HButton v-if="onTitleIndex == 1" is-modal type="primary" @click="onSave(1)">确定</HButton>
      <HButton v-else is-modal type="primary" @click="onSave(2)"> 确定</HButton>
      <HButton is-modal @click="onCancel">取消</HButton>
    </template>
  </HModal>
</template>

<script lang="ts" setup>
  import { ref, toRefs, watch } from 'vue'
  import {
    getOrderTableField,
    getOrderTableInitField,
    getOrderTableInitOrderByField,
    getOrderTableOrderByField,
    orderBySave,
    workTableFieldSave,
  } from '@/api/order'
  import { ElMessage } from 'element-plus'
  import {
    OrderTableInitField,
    OrderTableField,
    OrderSortField,
  } from '@/components/pages/order/TableColumnSet/types'
  import _ from 'lodash'
  import HButton from '@/components/common/button/HButton.vue'
  import HLink from './common/link/HLink.vue'
  import { Sort } from '@element-plus/icons-vue'
  import HModal from './common/Modal/HModal.vue'

  const props = defineProps({
    dialogTableVisible: Boolean,
    type: Number,
  })
  const { dialogTableVisible, type } = toRefs(props)
  const emits = defineEmits(['set-table-dialog', 'update-list'])
  const loading = ref(false)
  const HeaderDataList = ref<Array<OrderTableField>>([])
  const TableDataList = ref<Array<OrderSortField>>([])
  const onTitleIndex = ref(1)
  const numInput = ref() //输入的数字
  const popover = ref()
  const multipleTableRef = ref()

  // 选择列表数据
  const arrSelection = ref<Array<OrderTableField>>([])

  const options = ref(['更新时间', '创建时间', '完成时间', '取消时间'])

  const optionsTable = ref(['恢复默认', '升序', '降序'])
  const typeState = ref([
    { name: '全部工单', type: 1 },
    { name: '待派单', type: 2 },
    { name: '待网点处理', type: 3 },
    { name: '处理中', type: 4 },
    {
      name: '已完成',
      type: 5,
    },
    { name: '已取消', type: 6 },
  ])

  // 点击选择弹窗里的选项卡
  const onClickTitleIndex = (n) => {
    onTitleIndex.value = n
  }

  // 1表头 2列表
  watch(onTitleIndex, (n) => {
    arrSelection.value = []
    switch (n) {
      case 1:
        getHeaderDataList()
        break
      case 2:
        getTableDataList()
        break
    }
  })
  // 弹窗
  watch(dialogTableVisible, (val) => {
    if (val) {
      onTitleIndex.value = 1
      getHeaderDataList()
    }
  })
  const onCancel = () => {
    emits('set-table-dialog', false)
  }

  // 获取工单表头字段设置项
  const getHeaderDataList = async () => {
    loading.value = true
    const res = await getOrderTableField(type.value)
    if (res) {
      HeaderDataList.value = res.data.data.rows.map((o: OrderTableField, index: number) => {
        return { ...o, sort: index }
      })
    }
    loading.value = false
  }

  // 恢复成默认
  const onDefault = async () => {
    loading.value = true
    const res = await getOrderTableInitField()
    if (res) {
      /**
       * 1.提取初始化字段数组
       * 2.声明一个临时字段数组
       * 3.将符合条件的字段推到临时字段数组
       * 4.再次调整临时字段数组
       * 5.将临时字段数组更新到HeaderDataList中
       */
      const initFields: Array<OrderTableInitField> = res.data.data.rows
      let tempFieldList: Array<OrderTableField> = []
      initFields.forEach((initField) => {
        HeaderDataList.value.forEach((field) => {
          if (initField.id === field.admOrderTableFieldId) {
            tempFieldList.push(
              Object.assign(field, {
                admOrderTableFieldId: initField.id,
                freezeColumn: initField.freezeColumn,
                name: initField.name,
                showColumn: initField.showColumn,
              }),
            )
          }
        })
      })
      tempFieldList = tempFieldList.map((field, index) => {
        const __field = { ...field }
        __field.sort = index
        return __field
      })
      HeaderDataList.value = _.cloneDeep(tempFieldList)
    }
    loading.value = false
  }

  // 全部显示或隐藏
  const isShowAll = (param: boolean) => {
    HeaderDataList.value = HeaderDataList.value.map((o) => {
      return { ...o, showColumn: param }
    })
  }

  // 上移
  const onMoveUp = () => {
    if (arrSelection.value.length === 0) {
      ElMessage({
        message: '请选择要上移的项',
        type: 'warning',
        offset: 200,
      })

      return false
    }

    if (arrSelection.value.some((o) => o.sort === 0)) {
      ElMessage({
        message: '移动的项，已到达首行',
        type: 'warning',
        offset: 200,
      })
      return false
    }

    // 更新选中的元素的顺序
    arrSelection.value = arrSelection.value.sort((current, next) => current.sort - next.sort)

    for (let i = 0; i < arrSelection.value.length; i++) {
      // 获取要移动的字段
      const index = HeaderDataList.value.findIndex(
        (field) => field.name === arrSelection.value[i].name,
      )
      const moveField = HeaderDataList.value.splice(index, 1)[0]

      // 移动字段
      HeaderDataList.value.splice(index - 1, 0, moveField)

      // 更新sort属性值
      HeaderDataList.value.forEach((field, index) => {
        HeaderDataList.value[index].sort = index

        if (field.name === arrSelection.value[i].name) {
          arrSelection.value[i].sort = index
        }
      })
    }
  }

  // 下移
  const onMoveDown = () => {
    if (arrSelection.value.length === 0) {
      ElMessage({
        message: '请选择要下移的项',
        type: 'warning',
        offset: 200,
      })

      return false
    }

    if (arrSelection.value.some((o) => o.sort === HeaderDataList.value.length - 1)) {
      ElMessage({
        message: '移动的项，已到达尾行',
        type: 'warning',
        offset: 200,
      })
      return false
    }

    // 更新选中的元素的顺序
    arrSelection.value = arrSelection.value.sort((current, next) => current.sort - next.sort)

    for (let i = arrSelection.value.length - 1; i >= 0; i--) {
      // 获取要移动的字段
      const index = HeaderDataList.value.findIndex(
        (field) => field.name === arrSelection.value[i].name,
      )
      const moveField = HeaderDataList.value.splice(index, 1)[0]

      // 移动字段
      HeaderDataList.value.splice(index + 1, 0, moveField)

      // 更新sort值
      HeaderDataList.value.forEach((field, index) => {
        HeaderDataList.value[index].sort = index

        if (field.name === arrSelection.value[i].name) {
          arrSelection.value[i].sort = index
        }
      })
    }
  }

  // 全部冻结或解冻
  const onIsFreezeAll = (param: boolean) => {
    HeaderDataList.value = HeaderDataList.value.map((o) => {
      return { ...o, freezeColumn: param }
    })
  }

  // 移动到行首
  const onMoveFirst = () => {
    if (arrSelection.value[0].sort === 0) {
      ElMessage({
        message: '移动的项，已到达首行',
        type: 'warning',
        offset: 200,
      })
      return false
    }

    // 获取要移动的字段
    const selectionField = arrSelection.value[0]
    const index = HeaderDataList.value.findIndex(({ name }) => name === selectionField.name)

    // 移动字段
    const moveField = HeaderDataList.value.splice(index, 1)[0]
    HeaderDataList.value.splice(0, 0, moveField)

    // 更新sort值
    HeaderDataList.value.forEach((field, index) => {
      HeaderDataList.value[index].sort = index
    })
    arrSelection.value[0].sort = 0
  }

  // 移动到末尾
  const onMoveLast = () => {
    if (arrSelection.value[0].sort === HeaderDataList.value.length - 1) {
      ElMessage({
        message: '移动的项，已到达末尾',
        type: 'warning',
        offset: 200,
      })
      return false
    }

    // 获取要移动的字段
    const index = HeaderDataList.value.findIndex(({ name }) => name === arrSelection.value[0].name)
    const moveField = HeaderDataList.value.splice(index, 1)[0]

    // 移动字段
    HeaderDataList.value.splice(HeaderDataList.value.length, 0, moveField)

    // 更新sort值
    HeaderDataList.value.forEach((field, index) => {
      HeaderDataList.value[index].sort = index
    })
    arrSelection.value[0].sort = HeaderDataList.value.length - 1
  }

  // 移动到指定位置
  const onMoveTo = (position: number) => {
    if (arrSelection.value[0].sort === 0 && position <= 1) {
      ElMessage({
        message: '移动的项，已到达首行',
        type: 'warning',
        offset: 200,
      })
      return false
    }

    if (
      arrSelection.value[0].sort === HeaderDataList.value.length - 1 &&
      position >= HeaderDataList.value.length - 1
    ) {
      ElMessage({
        message: '移动的项，已到达末尾',
        type: 'warning',
        offset: 200,
      })
      return false
    }

    // 合成字段到达的目标位置
    let __position = position - 1
    if (__position > HeaderDataList.value.length - 1) {
      __position = HeaderDataList.value.length
    }

    if (__position < 0) {
      __position = 1
    }

    // 更新数据在数组的位置
    const index = HeaderDataList.value.findIndex(
      (field) => field.name === arrSelection.value[0].name,
    )
    HeaderDataList.value.splice(__position, 0, HeaderDataList.value.splice(index, 1)[0])

    // 更新sort属性值
    HeaderDataList.value.forEach((field, fieldIndex) => {
      HeaderDataList.value[fieldIndex].sort = fieldIndex
    })
    arrSelection.value[0].sort = __position
  }

  //  获取工单列表排序字段设置
  const getTableDataList = async () => {
    loading.value = true
    const res = await getOrderTableOrderByField(type.value)
    if (res) {
      TableDataList.value = res.data.data.rows
    }
    loading.value = false
  }

  // 显示前触发
  const popoverShow = () => {
    if (arrSelection.value.length == 0) {
      ElMessage({
        message: '请选择要移动的项',
        type: 'warning',
        offset: 200,
      })
      popover.value.hide()
    } else if (arrSelection.value.length > 1) {
      ElMessage({
        message: '仅可以选择一项移动',
        type: 'warning',
        offset: 200,
      })
      popover.value.hide()
    }
  }

  // 点击列表设置 '恢复默认', '升序', '降序'
  const onClickoptionsTableData = async (n) => {
    if (n === 0) {
      loading.value = true
      const res = await getOrderTableInitOrderByField()
      if (res) {
        TableDataList.value = res.data.data.rows.map((o) => {
          return { ...o, admOrderByFieldId: o.id, id: null }
        })
      }
      loading.value = false
      return false
    }

    if (n === 1) {
      if (arrSelection.value.length == 0) {
        ElMessage({
          message: '请选择要升序的项',
          type: 'warning',
          offset: 200,
        })
      } else {
        // TODO 类型问题
        TableDataList.value = TableDataList.value.map((o) => {
          if (arrSelection.value.some((i) => i.admOrderByFieldId == o.admOrderByFieldId)) {
            o.orderBy = 1
          }
          return o
        })
      }
      return false
    }

    if (n === 2) {
      if (arrSelection.value.length == 0) {
        ElMessage({
          message: '请选择要降序的项',
          type: 'warning',
          offset: 200,
        })
      } else {
        // TODO 类型问题
        TableDataList.value = TableDataList.value.map((o) => {
          if (arrSelection.value.some((i) => i.admOrderByFieldId == o.admOrderByFieldId)) {
            o.orderBy = 2
          }
          return o
        })
      }
      return false
    }
  }
  // 保存
  const onSave = async (n) => {
    if (n == 1) {
      loading.value = true
      await workTableFieldSave(HeaderDataList.value, type.value).then((res) => {
        if (res) {
          ElMessage({
            message: res.data.message,
            type: res.data.success ? 'success' : 'error',
          })
          if (res.data.success) {
            onCancel()
            emits('update-list')
          }
        }
      })
      loading.value = false
    }
    if (n == 2) {
      loading.value = true
      await orderBySave(TableDataList.value, type.value).then((res) => {
        if (res) {
          ElMessage({
            message: res.data.message,
            type: res.data.success ? 'success' : 'error',
          })
          if (res.data.success) {
            onCancel()
            emits('update-list')
          }
        }
      })
      loading.value = false
    }
  }

  const dragIndex = ref() //记录移动停放位置index
  // 鼠标移动过程触发
  const dragover = (e: { preventDefault: () => void }) => {
    e.preventDefault()
  }
  // 鼠标不移动时一直触发
  const dragenter = (e: { preventDefault: () => void }, index) => {
    e.preventDefault()
    dragIndex.value = index
  }
  // 鼠标停止触发 index==>被移动的元素下标
  const dragend = (index) => {
    if (dragIndex.value !== index) {
      const moving = HeaderDataList.value[index] // 移动的项
      HeaderDataList.value.splice(index, 1)
      HeaderDataList.value.splice(dragIndex.value, 0, moving)
      HeaderDataList.value = HeaderDataList.value.map((o, index) => {
        return { ...o, sort: index }
      })
    }
  }

  // 选择列表数据
  const handleSelectionChange = (fields: Array<OrderTableField>) => {
    arrSelection.value = []
    fields.forEach((field) => {
      const __field = { ...field }
      arrSelection.value.push(__field)
    })
  }
</script>

<style lang="scss">
  .header_Table {
    display: flex;

    .title_xy {
      margin: 0 12px 12px;
      padding-bottom: 8px;
      cursor: pointer;
      position: relative;
      color: #999;

      &.title_color {
        color: #007cff;

        &::after {
          content: '';
          height: 2px;
          width: 100%;
          box-sizing: border-box;
          background-color: #007cff;
          position: absolute;
          bottom: 0;
          left: 0;
          right: 0;
          margin: 0 auto;
        }
      }

      &:hover {
        color: #007cff;
      }
    }
  }

  :deep(.style_txt) {
    cursor: pointer;
    color: #007cff;
  }

  .operate_btn_group {
    display: flex;
    gap: 12px;
    justify-content: flex-end;
    margin-bottom: 20px;
  }

  .list_option {
    display: flex;
    gap: 10px;
    margin-bottom: 10px;
    justify-content: flex-end;

    .item_option {
      font-size: 12px;
      color: $primaryColor;
      cursor: pointer;

      &:hover {
        color: rgba($color: $primaryColor, $alpha: 0.6);
      }
    }
  }
</style>
